#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/epoll.h>

#define MAX_EVENTS 1000
#define BUFFER_SIZE 1024

int main() {
    int server_fd, client_fd, epoll_fd, nfds, i;
    struct sockaddr_in address;
    struct epoll_event ev, events[MAX_EVENTS];
    char buffer[BUFFER_SIZE];

    // 1. 创建服务器socket
    server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd < 0) {
        perror("socket creation failed");
        return 1;
    }

    int optval=1;
    setsockopt(server_fd, SOL_SOCKET, SO_REUSEPORT, &optval, 4);
    setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &optval, 4);
    // 2. 绑定地址
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(8080);
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("bind failed");
        return 1;
    }

    // 3. 监听连接
    if (listen(server_fd, 5) < 0) {
        perror("listen failed");
        return 1;
    }

    // 4. 创建epoll实例
    epoll_fd = epoll_create1(0);
    if (epoll_fd < 0) {
        perror("epoll_create1 failed");
        return 1;
    }

    // 5. 将server_fd添加到epoll监听
    ev.events = EPOLLIN;  // 监听可读事件
    ev.data.fd = server_fd; 
    // epoll_ctl 成功返回 0，失败-1
    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &ev) < 0) {
        perror("epoll_ctl failed");
        return 1;
    }

    printf("Server started on port 8080...\n");

    // 6. 主循环：使用epoll_wait监听事件
    while (1) {
        // 等待事件发生（超时时间设为-1，永久阻塞）
        // epoll_wait()返回FD就绪的个数
        nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
        if (nfds < 0) {
            perror("epoll_wait failed");
            break;
        }

        // 处理所有就绪的事件
        for (i = 0; i < nfds; i++) {
            // 7. 处理新连接
            if (events[i].data.fd == server_fd) {
                struct sockaddr_in client_addr;
                socklen_t client_len = sizeof(client_addr);
                client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_len);
                if (client_fd < 0) {
                    perror("accept failed");
                    continue;
                }

                // 打印客户端信息
                char client_ip[INET_ADDRSTRLEN];
                inet_ntop(AF_INET, &client_addr.sin_addr, client_ip, sizeof(client_ip));
                printf("New client connected: %s:%d\n", client_ip, ntohs(client_addr.sin_port));

                // 将新客户端添加到epoll监听
                ev.events = EPOLLIN | EPOLLET;  // 使用边缘触发模式
                ev.data.fd = client_fd;
                if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &ev) < 0) {
                    perror("epoll_ctl failed");
                    close(client_fd);
                }
            }
            // 8. 处理客户端数据
            else {
                client_fd = events[i].data.fd;
                int bytes_read = read(client_fd, buffer, BUFFER_SIZE);
                if (bytes_read <= 0) {
                    // 发生错误，关闭连接
                    perror("read error或client closing...\n");
                    close(client_fd);
                    // 客户端关闭后，需要从epollfd中删除中，即不监听了
                    epoll_ctl(epoll_fd, EPOLL_CTL_DEL, client_fd, NULL);
                }  else {
                    // 处理数据（示例：回显给客户端）
                    buffer[bytes_read] = '\0';
                    printf("Received: %s\n", buffer);
                    write(client_fd, buffer, bytes_read);
                }
            }
        }
    }

    // 清理资源
    close(server_fd);
    close(epoll_fd);
    return 0;
}